home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / vol11n07.zip / DEMO6.C < prev    next >
Text File  |  1992-02-08  |  16KB  |  380 lines

  1. // DEMO6.C --- Pen-centric Windows application that demonstrates 
  2. // handwritten input using the Recognize() function.
  3. // Copyright (C) 1992 Ray Duncan
  4.  
  5. #define WIN31
  6. #define dim(x) (sizeof(x) / sizeof(x[0]))   // returns no. of elements
  7. #define BUFMAX 80                           // size of scratch buffers
  8.  
  9. #include "windows.h"
  10. #include "penwin.h"
  11. #include "demo6.h"
  12.  
  13. HANDLE hInst;                               // instance handle
  14. HWND hWndFrame = 0;                         // frame window handle
  15. HWND hWndText = 0;                          // child text window handle
  16. HWND hWndWrite = 0;                         // child writing window handle
  17. HANDLE hPenWin = 0;                         // Pen Windows module handle
  18.  
  19. int CharX = 0;                              // average char width
  20. int CharY = 0;                              // char height
  21. int CurLine = 0;                            // current line number
  22. int MaxLine = 0;                            // maximum line number
  23. int EnumCount = 0;                          // translation counter
  24.  
  25. char szFrameClass[] = "DemoFrameClass";     // name of frame window class
  26. char szTextClass[]  = "DemoTextClass";      // child text window class
  27. char szWriteClass[] = "DemoWriteClass";     // child writing window class
  28.  
  29. struct {                                    // result codes returned
  30.     int Code;                               // by Recognize() function
  31.     char * Name;
  32.     } recogResults[] = {
  33.     REC_OK, "REC_OK",
  34.     REC_ABORT, "REC_ABORT",
  35.     REC_BADHPENDATA, "REC_BADHPENDATA",
  36.     REC_BUFFERTOOSMALL, "REC_BUFFERTOOSMALL",
  37.     REC_BUSY, "REC_BUSY",
  38.     REC_DONE, "REC_DONE",
  39.     REC_NOINPUT, "REC_NOINPUT",
  40.     REC_NOTABLET, "REC_NOTABLET",
  41.     REC_OOM, "REC_OOM",
  42.     REC_OVERFLOW, "REC_OVERFLOW",
  43.     REC_TERMBOUND, "REC_TERMBOUND",
  44.     REC_TERMEX, "REC_TERMEX",
  45.     REC_TERMOEM, "REC_TERMOEM",
  46.     REC_TERMPENUP, "REC_TERMPENUP",
  47.     REC_TERMRANGE, "REC_TERMRANGE",
  48.     REC_TERMTIMEOUT, "REC_TERMTIMEOUT", } ;
  49.  
  50. struct {                                    // result types returned
  51.     int Code;                               // in RCRESULT structure
  52.     char * Name;
  53.     } rctypeResults[] = {
  54.     RCRT_UNIDENTIFIED, "RCRT_UNIDENTIFIED",
  55.     RCRT_GESTURE, "RCRT_GESTURE",   
  56.     RCRT_NOSYMBOLMATCH, "RCRT_NOSYMBOLMATCH",    
  57.     RCRT_PRIVATE, "RCRT_PRIVATE",
  58.     RCRT_NORECOG, "RCRT_NORECOG",
  59.     RCRT_ALREADYPROCESSED, "RCRT_ALREADYPROCESSED",
  60.     RCRT_GESTURETRANSLATED, "RCRT_GESTURETRANSLATED",
  61.     RCRT_GESTURETOKEYS, "RCRT_GESTURETOKEYS", } ;
  62.  
  63. //
  64. // WinMain --- entry point from Windows.  Registers window classes,
  65. // creates windows, registers pen app, and processes messages until 
  66. // WM_QUIT received.
  67. //
  68. int PASCAL WinMain(HANDLE hInstance, 
  69.     HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  70. {
  71.     MSG msg;                     
  72.  
  73.     hInst = hInstance;                      // save this instance handle
  74.  
  75.     if(!hPrevInstance)                      // if first instance,
  76.         if(!InitApplication(hInstance))     // register window class
  77.             return(FALSE);                  // exit if couldn't register
  78.  
  79.     if(!InitInstance(hInstance, nCmdShow))  // create this instance's window
  80.     {
  81.         MessageBox(0, "Initialization failed!", "DEMO6", MB_OK|MB_ICONSTOP);
  82.         return(FALSE);
  83.     }
  84.  
  85.     RegisterPenApp(RPA_DEFAULT, TRUE);      // enable HEDIT/BEDIT controls
  86.  
  87.     while(GetMessage(&msg, NULL, 0, 0))     // while message != WM_QUIT
  88.     {
  89.         TranslateMessage(&msg);             // translate virtual key codes
  90.         DispatchMessage(&msg);              // dispatch message to window
  91.     }
  92.     return(msg.wParam);                     // return code = WM_QUIT value
  93. }
  94.  
  95. //
  96. // InitApplication --- registers window classes for this application
  97. //
  98. BOOL InitApplication(HANDLE hInstance)
  99. {
  100.     WNDCLASS  wc;
  101.     BOOL bParent;
  102.     BOOL bText;
  103.     BOOL bWrite;
  104.  
  105.     // set parameters for frame window class
  106.     wc.style = CS_HREDRAW | CS_VREDRAW;     // class style
  107.     wc.lpfnWndProc = FrameWndProc;           // class callback function
  108.     wc.cbClsExtra = 0;                      // extra per-class data
  109.     wc.cbWndExtra = 0;                      // extra per-window data
  110.     wc.hInstance = hInstance;               // handle of class owner
  111.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);     // default icon
  112.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);       // default cursor
  113.     wc.hbrBackground = GetStockObject(WHITE_BRUSH); // background color 
  114.     wc.lpszMenuName =  "DemoMenu";          // name of menu resource
  115.     wc.lpszClassName = szFrameClass;        // name of window class
  116.  
  117.     bParent = RegisterClass(&wc);           // register frame window class
  118.  
  119.     // set parameters for text output child window class
  120.     wc.lpfnWndProc = TextWndProc;           // class callback function
  121.     wc.hIcon = NULL;                        // default icon
  122.     wc.lpszMenuName =  NULL;                // name of menu resource
  123.     wc.lpszClassName = szTextClass;         // name of window class
  124.  
  125.     bText = RegisterClass(&wc);             // register text child class
  126.  
  127.     // set parameters for writing input child window class
  128.     wc.lpfnWndProc = WriteWndProc;          // class callback function
  129.     wc.lpszClassName = szWriteClass;        // name of window class
  130.  
  131.     bWrite = RegisterClass(&wc);            // register writing child class
  132.  
  133.     return(bParent && bText && bWrite);     // return success/failure flag
  134. }
  135.  
  136. //
  137. // InitInstance --- creates frame window for this application instance
  138. //
  139. BOOL InitInstance(HANDLE hInstance, int nCmdShow)
  140. {
  141.     hWndFrame = CreateWindow(               // create frame window
  142.         szFrameClass,                       // window class name
  143.         "Pen Windows Demo #6",              // text for title bar
  144.         WS_OVERLAPPEDWINDOW,                // window style
  145.         CW_USEDEFAULT, CW_USEDEFAULT,       // default position
  146.         CW_USEDEFAULT, CW_USEDEFAULT,       // default size
  147.         NULL,                               // no parent window
  148.         NULL,                               // use class default menu
  149.         hInstance,                          // window owner
  150.         NULL                                // unused pointer
  151.     );
  152.  
  153.     if(!hWndFrame) return(FALSE);           // error, can't create window
  154.  
  155.     ShowWindow(hWndFrame, nCmdShow);        // make frame window visible
  156.     UpdateWindow(hWndFrame);                // force WM_PAINT message
  157.     return(TRUE);                           // return success flag
  158. }
  159.  
  160. //
  161. // FrameWndProc --- callback function for application frame window
  162. //
  163. long FAR PASCAL FrameWndProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
  164. {
  165.     switch (wMsg) 
  166.     {
  167.         case WM_CREATE:                     // creating frame window
  168.             hWndText = CreateWindow(        // create child text window
  169.                 szTextClass,                // window class name
  170.                 NULL,                       // text for title bar
  171.                 WS_CHILDWINDOW | WS_VISIBLE | WS_BORDER,    // style
  172.                 0, 0, 0, 0,                 // position and size
  173.                 hWnd,                       // frame window is parent 
  174.                 0,                          // child window identifier
  175.                 hInst,                      // window owner
  176.                 NULL);                      // unused pointer
  177.             hWndWrite = CreateWindow(       // create child writing window
  178.                 szWriteClass,               // window class name
  179.                 NULL,                       // text for title bar
  180.                 WS_CHILDWINDOW | WS_VISIBLE | WS_BORDER,    // style
  181.                 0, 0, 0, 0,                 // position and size
  182.                 hWnd,                       // frame window is parent 
  183.                 0,                          // child window identifier
  184.                 hInst,                      // window owner
  185.                 NULL);                      // unused pointer
  186.             break;
  187.  
  188.         case WM_SIZE:                       // resize & position children:
  189.             MoveWindow(hWndWrite,           // writing input window 
  190.                 0, 0, LOWORD(lParam)/2, HIWORD(lParam), TRUE);
  191.             MoveWindow(hWndText,            // text output window
  192.                 LOWORD(lParam)/2, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
  193.             return(0);
  194.  
  195.         case WM_COMMAND:                    // menu command received,
  196.             DoCommand(hWnd, wParam);        // decode it
  197.             break;
  198.  
  199.         case WM_DESTROY:                    // window being destroyed
  200.             PostQuitMessage(0);             // force WM_QUIT message
  201.             break;
  202.  
  203.         default:                            // let Windows handle it
  204.             return(DefWindowProc(hWnd, wMsg, wParam, lParam));
  205.     }
  206.  
  207.     return(0);
  208. }
  209.  
  210. //
  211. // TextWndProc --- callback function for child text window
  212. //
  213. long FAR PASCAL TextWndProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
  214. {
  215.     TEXTMETRIC tm;
  216.     HDC hdc;
  217.     LPRCRESULT rcresult;                    // recognition results
  218.     FARPROC lpProc;                         // far pointer for callback 
  219.     char buff1[BUFMAX];                     // scratch buffer
  220.     char buff2[BUFMAX];                     // scratch buffer
  221.     int i;                                  // scratch variable
  222.  
  223.     switch(wMsg)
  224.     {
  225.         case WM_CREATE:                     // creating text child window
  226.             hdc = GetDC(hWnd);              // get device context
  227.             GetTextMetrics(hdc, &tm);       // get text metrics
  228.             CharX = tm.tmAveCharWidth;      // save character size
  229.             CharY = tm.tmHeight + tm.tmExternalLeading;
  230.             ReleaseDC(hWnd, hdc);           // release device context
  231.             return(0);
  232.  
  233.         case WM_SIZE:                       // resize/position in progress
  234.             CurLine = 0;                    // reset current line number
  235.             MaxLine = HIWORD(lParam)/CharY; // no. of lines in window
  236.             return(0);
  237.  
  238.         case WM_RCRESULT:                   // display recognition results
  239.             rcresult = (LPRCRESULT) lParam; // get pointer to results
  240.             DisplayLine("Message WM_RCRESULT received.");
  241.             for(i = 0; i < dim(rctypeResults); i++)
  242.             {                               // decode result type
  243.                 if(rctypeResults[i].Code & rcresult->wResultsType)
  244.                 {
  245.                     wsprintf(buff1, "Result type code: %s.", 
  246.                         (LPSTR) rctypeResults[i].Name);
  247.                     DisplayLine(buff1);     // display result type
  248.                 }
  249.             }
  250.             SymbolToCharacter(rcresult->lpsyv, BUFMAX, buff2, NULL);
  251.             wsprintf(buff1, "Preferred translation is: %s.", (LPSTR) buff2);
  252.             DisplayLine(buff1);             // display best bet string
  253.             wsprintf(buff1, "Symbol graph has %d possible translations.",
  254.                 GetSymbolCount(&(rcresult->syg)));   
  255.             DisplayLine(buff1);             // display no. of candidates
  256.             EnumCount = 0;                  // display each candidate
  257.             lpProc = MakeProcInstance(EnumFunc, hInst);
  258.             EnumSymbols(&(rcresult->syg), 1000, lpProc, NULL);
  259.             FreeProcInstance(lpProc);
  260.             return(0);
  261.  
  262.         default:
  263.             return(DefWindowProc(hWnd, wMsg, wParam, lParam));
  264.     }
  265. }
  266.  
  267. //
  268. // WriteWndProc --- callback function for child writing window
  269. //
  270. long FAR PASCAL WriteWndProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
  271. {
  272.     RC rc;                                  // recognition context
  273.     HDC hdc;                                // device context handle
  274.     PAINTSTRUCT ps;                         // painting info structure
  275.     RECT rect;                              // receives client rectangle
  276.     REC result;                             // status from Recognize()
  277.     char buff1[BUFMAX];                     // scratch buffer
  278.     int i;                                  // scratch variable
  279.  
  280.     switch(wMsg)
  281.     {
  282.         case WM_PAINT:                      // window needs repainting
  283.             hdc = BeginPaint(hWnd, &ps);    // get device context
  284.             GetClientRect(hWnd, &rect);     // get client rectangle
  285.             DrawText(hdc,                   // put legend in writing area
  286.                 "Writing Area", -1, &rect, 
  287.                 DT_CENTER | DT_TOP | DT_SINGLELINE);
  288.             EndPaint(hWnd, &ps);            // release device context
  289.             break;
  290.  
  291.         case WM_LBUTTONDOWN:                // mouseclick starts pen input
  292.             if(IsPenEvent(wMsg, GetMessageExtraInfo()))
  293.             {
  294.                 InvalidateRect(hWnd, NULL, TRUE);   // erase both windows
  295.                 UpdateWindow(hWnd);         
  296.                 InvalidateRect(hWndText, NULL, TRUE);   
  297.                 UpdateWindow(hWndText);         
  298.                 CurLine = 0;                // reset current line number
  299.                 DisplayLine("Initializing RC structure.");
  300.                 InitRC(hWndWrite, &rc);     // set default RC values
  301.                 rc.hwnd = hWndText;         // text window gets results
  302.                 rc.rglpdf[0] = NULL;        // assume no dictionary
  303.                 DisplayLine("Calling Recognize function.");
  304.                 result = Recognize(&rc);    // request pen input
  305.                 strcpy(buff1, "Recognize result code: unknown.");
  306.                 for(i = 0; i < dim(recogResults); i++)
  307.                 {                           // decode Recognize() status
  308.                     if(recogResults[i].Code == result)
  309.                         wsprintf(buff1, "Recognize result code: %s.", 
  310.                             (LPSTR) recogResults[i].Name);
  311.                 }
  312.                 DisplayLine(buff1);         // display Recognize() status   
  313.             };
  314.             return(0);
  315.  
  316.         default:
  317.             return(DefWindowProc(hWnd, wMsg, wParam, lParam));
  318.     }
  319. }
  320.  
  321. // 
  322. // DisplayLine --- displays a string in the text output child window
  323. //
  324. void DisplayLine(char * szOut)
  325. {
  326.     RECT rect;
  327.     HDC hdc;
  328.  
  329.     hdc = GetDC(hWndText);                  // get device context
  330.     GetClientRect(hWndText, &rect);         // get client rectangle
  331.     if(CurLine == MaxLine)                  // at bottom of window?
  332.     {
  333.         ScrollWindow(hWndText, 0, -CharY,   // yes, scroll window up
  334.             NULL, NULL);    
  335.         UpdateWindow(hWndText);
  336.         CurLine--;
  337.     }
  338.     TextOut(hdc, 0, CurLine * CharY,        // display text in window
  339.         szOut, strlen(szOut));
  340.     CurLine++;                              // move to next line
  341.     ReleaseDC(hWndText, hdc);               // release device context
  342.     return;
  343. }
  344.  
  345. //
  346. // DoCommand --- handles menu command messages for the frame window
  347. //
  348. void DoCommand(HWND hWnd, WORD wParam)
  349. {
  350.     FARPROC lpProc;                         // far pointer to callback 
  351.  
  352.     switch(wParam)                          // decode it
  353.     {
  354.         case IDM_EXIT:                      // user picked File-Quit
  355.             SendMessage (hWnd, WM_CLOSE, 0, 0L);
  356.             break;
  357.  
  358.         default:                            // unknown command, ignore it
  359.             break;
  360.     }
  361. }
  362.  
  363. //
  364. // EnumFunc --- the callback function for EnumSymbols().  During
  365. // evaluation of a symbol graph, this function is entered 
  366. // repetitively with a pointer to each candidate symbol array.
  367. // The symbol array is translated to a character string and displayed.
  368. //
  369. int FAR PASCAL EnumFunc(LPSYV lpSyv, int cSyv, VOID FAR * lpData)
  370. {
  371.     char buff1[BUFMAX];                     // scratch buffer
  372.     char buff2[BUFMAX];                     // scratch buffer
  373.  
  374.     SymbolToCharacter(lpSyv, BUFMAX, buff2, NULL);
  375.     wsprintf(buff1, "Translation #%d is: %s.", ++EnumCount, (LPSTR) buff2);
  376.     DisplayLine(buff1);
  377.     return(TRUE);                           // TRUE to continue enumeration
  378. }
  379.  
  380.